package com.test.PSO;

import com.test.BRBInference.BRBInference;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;

@WebServlet(name = "PSOServlet",value = "/PSOServlet")
public class PSOServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        HttpSession session = request.getSession();
        ArrayList<Object[]> modelList = (ArrayList<Object[]>) session.getAttribute("modelList");
        ArrayList<Object[]> dataList = (ArrayList<Object[]>) session.getAttribute("dataList");
        ArrayList<ArrayList<Integer>> attrArray = (ArrayList<ArrayList<Integer>>) session.getAttribute("Contri_num");
        ArrayList<Object> inference_result_list = (ArrayList<Object>) session.getAttribute("Inference_Result");
        ArrayList<Object> uscale_temp =(ArrayList<Object>)session.getAttribute("uscale");

        ArrayList<ArrayList<Double>> modelArray = new ArrayList<ArrayList<Double>>();

        for (Object[] rule : modelList) {
            ArrayList<Double> model = new ArrayList<Double>();
            for (Object value : rule) {
                double temp = Double.parseDouble(value.toString());
                //System.out.println(temp);
                model.add(temp);
            }
            model.remove(0);
            modelArray.add(model);
        }


        ArrayList<ArrayList<Double>> dataArray = new ArrayList<ArrayList<Double>>();

        for (Object[] attr : dataList) {
            ArrayList<Double> data = new ArrayList<Double>();
            for (Object value : attr) {
                double temp = Double.parseDouble(value.toString());
                //System.out.println(temp);
                data.add(temp);
            }
            data.remove(0);
            dataArray.add(data);
        }

        ArrayList<Double> uscale = new ArrayList<>();
        for(Object value : uscale_temp) {
            uscale.add(Double.parseDouble(value.toString()));
        }

        ArrayList<Double> inference_result = new ArrayList<>();
        for(Object value : inference_result_list) {
            inference_result.add(Double.parseDouble(value.toString()));
        }

        for (int i = 0; i < attrArray.size(); ++i) {
            for (int j = 0; j < attrArray.get(i).size(); ++j) {
                attrArray.get(i).set(j, attrArray.get(i).get(j) - 1);
            }
        }

        ArrayList<Double> optimal_Result = new ArrayList<>();
        ArrayList<Double> optimal_Result2 = new ArrayList<>();

        ArrayList<ArrayList<Double>> optimal_data = new ArrayList<>();
        for (int num = 0; num < dataArray.size(); ++num) {
            ArrayList<Double> data = dataArray.get(num);
            ArrayList<Integer> attr = attrArray.get(num);

            PSO pso = new PSO(uscale, data, modelArray, attr);
            pso.Init();
            pso.Process();

            double gap = BRBInference.abs(inference_result.get(num)) - pso.getZbestfitness();
            if(gap<0) {
                ArrayList<ArrayList<Double>> dataArray_temp = new ArrayList<>();
                dataArray_temp.add(data);
                BRBInference BRB = new BRBInference(uscale,dataArray_temp,modelArray);
                BRB.attr_identify();
                BRB.fuse();
                optimal_Result.add(BRB.getInference_Result().get(0));
                data.remove(data.size()-1);
                optimal_data.add(data);
                gap = 0.0;
            } else {
                if(inference_result.get(num)<0) {
                    optimal_Result.add(-(pso.getZbestfitness()));
                } else {
                    optimal_Result.add(pso.getZbestfitness());
                }
                pso.getZbest().remove(pso.getZbest().size()-1);
                optimal_data.add(pso.getZbest());
            }
            optimal_Result2.add(gap);
        }

        ArrayList<Double> optimal_Result_round = BRBInference.round(optimal_Result);
        ArrayList<Double> optimal_Result2_round = BRBInference.round(optimal_Result2);
        ArrayList<ArrayList<Double>> optimal_data_round = BRBInference.Round(optimal_data);

        request.getSession().setAttribute("pso_result", optimal_Result_round);
        request.getSession().setAttribute("optimal_result", optimal_Result2_round);
        request.getSession().setAttribute("pso_data", optimal_data_round);

        response.sendRedirect("/Java_web/Optimation.jsp");

    }



    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}
